package org.example;

import java.util.ArrayList;
import java.util.List;

// 数组：一维数组和二维数组
public class Arrays {

    // 二维数组寻找上、右上、右、右下、下、左下、左、左上
    // 使用偏移量数组(方向数组)，在DFS.java中可以查阅
    // int[][] offsets = {
    //    {-1, 0}, {-1, 1}, {0, 1}, {1, 1},
    //    {1, 0}, {1, -1}, {0, -1}, {-1, -1}
    //};
    static class Arrays11 {
        /**
         * 寻找当前坐标的周围坐标
         *
         * @param matrix 二维坐标
         * @param row    表示当前行
         * @param col    表示当前列
         * @return
         */
        List<int[]> findAllCoordinates(int[][] matrix, int row, int col) {
            List<int[]> coordinates = new ArrayList<>();
            int rows = matrix.length;
            int cols = matrix[0].length;

            // 偏移量数组，分别表示：上，右上，右，右下，下，左下，左，左上
            int[][] offsets = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
            for (int[] offset : offsets) {
                int newX = row + offset[0];
                int newY = col + offset[1];
                // 检查新坐标是否在数组范围内
                if (newX >= 0 && newX < rows && newY >= 0 && newY < cols) {
                    coordinates.add(new int[]{newX, newY});
                }
            }
            return coordinates;
        }

        /**
         * 寻找当前坐标的对角线上所有坐标位置
         *
         * @param matrix 二维坐标
         * @param row    表示当前行
         * @param col    表示当前列
         * @return
         */
        List<int[]> findDiagonalCoordinates(int[][] matrix, int row, int col) {
            List<int[]> coordinates = new ArrayList<>();
            int rows = matrix.length;
            int cols = matrix[0].length;

            // 偏移量数组，分别表示右上、右下、左下、左上
            int[][] offsets = {{-1, 1}, {1, 1}, {1, -1}, {-1, -1}};
            for (int[] offset : offsets) {
                int newX = row + offset[0];
                int newY = col + offset[1];
                // 检查新坐标是否在数组范围内
                while (newX >= 0 && newX < rows && newY >= 0 && newY < cols) {
                    coordinates.add(new int[]{newX, newY});
                    newX += offset[0];
                    newY += offset[1];
                }
            }
            return coordinates;
        }

        /**
         * 在二维数组中，根据某个坐标点，得到该坐标点的区域范围，比如9*9的范围内，查找某个坐标的所属的3*3的范围
         * int[][] sudoku = {
         *         {5, 3, 4,| 6, 7, 8,| 9, 1, 2},
         *         {6, 7, 2,| 1, 9, 5,| 3, 4, 8},
         *         {1, 9, 8,| 3, 4, 2,| 5, 6, 7},
         *         ---------|---------|---------
         *         {8, 5, 9,| 7, 6, 1,| 4, 2, 3},
         *         {4, 2, 6,| 8, 5, 3,| 7, 9, 1},
         *         {7, 1, 3,| 9, 2, 4,| 8, 5, 6},
         *         ---------|---------|---------
         *         {9, 6, 1,| 5, 3, 7,| 2, 8, 4},
         *         {2, 8, 7,| 4, 1, 9,| 6, 3, 5},
         *         {3, 4, 5,| 2, 8, 6,| 1, 7, 9}
         * };
         * @param sudoku 二维数组
         * @param row    当前行
         * @param col    当前列
         * @param range  范围大小
         * @return
         */
        List<int[]> getSubgridCoordinates(int[][] sudoku, int row, int col, int range) {
            List<int[]> result = new ArrayList<>();
            int startRow = (row / range) * range;
            int startCol = (col / range) * range;
            for (int i = startRow; i < startRow + range; i++) {
                for (int j = startCol; j < startCol + range; j++) {
                    // 这里对sudoku数组并未做任何操作
                    result.add(new int[]{i, j}); // 这里仅存放的坐标位置
                }
            }
            return result;
        }

        // N皇后检查45度对角线和135度对角线
        public boolean isValid(int row, int col, int n, char[][] chessboard) {
            // 检查列
            for (int i = 0; i < row; ++i) {
                if (chessboard[i][col] == 'Q') {
                    return false;
                }
            }
            // 检查45度对角线，这边仅对左上角对角线，因为当前[row, col]还未执行下个步骤
            for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
                if (chessboard[i][j] == 'Q') {
                    return false;
                }
            }

            // 检查45度对角线, 如果部分场景需要检查左下角
            /*for (int i = row + 1, j = col - 1; i <= n-1 && j >= 0; i++, j--) {
                if (chessboard[i][j] == 'Q') {
                    return false;
                }
            }*/

            // 检查135度对角线，这边仅对右上角对角线，因为当前[row, col]还未执行下个步骤
            for (int i = row - 1, j = col + 1; i >= 0 && j <= n - 1; i--, j++) {
                if (chessboard[i][j] == 'Q'){
                    return false;
                }
            }

            // 检查135度对角线, 如果部分场景需要检查右下角
            /*for (int i = row + 1, j = col + 1; i <= n-1 && j <= n - 1; i++, j++) {
                if (chessboard[i][j] == 'Q'){
                    return false;
                }
            }*/
            return true;
        }
    }

}
